package com.cars.satoken.controller;

import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cars.satoken.entities.User;
import com.cars.satoken.service.UserService;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.*;

/**
 * 登录测试
 *
 * @author: caoqianfan
 * @date: 2023/9/27 15:19
 */
@RestController
@RequestMapping("/login")
public class LoginController {
    @Resource
    private UserService userService;

    /**
     * do login
     *
     * @param userDTO         用户数据传输对象
     * @param isLastingCookie 是否持久化Cookie
     * @return {@code SaResult}
     */// 测试登录  ---- http://localhost:8081/login/doLogin?name=zhang&pwd=123456
    @PostMapping("/doLogin")
    public SaResult doLogin(@RequestBody User userDTO, @RequestParam(required = false, defaultValue = "false") Boolean isLastingCookie) {
        User userDO = userService.getOne(new QueryWrapper<User>().eq("name", userDTO.getName()));
        // 在登录时缓存 userDTO 对象
        StpUtil.getSession().set("current-user", userDO);
        if (userDO != null && BCrypt.checkpw(userDTO.getPassword(), userDO.getPassword())) {
            Long id = userDO.getId();
            // 校验指定账号是否已被封禁，如果被封禁则抛出异常 `DisableServiceException`
            StpUtil.checkDisable(id);
            // 持久化cookie
            StpUtil.login(id, isLastingCookie);
            SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
            // 后端将 token 返回到前端
            return SaResult.data(tokenInfo);
        }
        return SaResult.error("登录失败");
    }

    // 查询登录状态  ---- http://localhost:8081/login/isLogin
    @GetMapping("/isLogin")
    public SaResult isLogin() {
        return SaResult.ok("是否登录：" + StpUtil.isLogin());
    }

    // 查询 Token 信息  ---- http://localhost:8081/login/tokenInfo
    @GetMapping("/tokenInfo")
    public SaResult tokenInfo() {
        return SaResult.data(StpUtil.getTokenInfo());
    }

    // 测试注销  ---- http://localhost:8081/login/logout
    @PostMapping("/logoutSelf")
    public SaResult logoutSelf() {
        User user = StpUtil.getSession().getModel("current-user", User.class);
        Long id = user.getId();
        // 注销当前用户的 Session 会话 (从持久库删除此Session)
        SaSession session = StpUtil.getSession();
        if (session != null) {
            session.logout();
        }
        //登出当前账号
        StpUtil.logout(id);
        return SaResult.ok();
    }

    /**
     * logout
     *
     * @param userDTO user dto
     * @return {@code SaResult}
     */
    @PostMapping("/logout")
    public SaResult logout(@RequestBody User userDTO) {
        Long id = userDTO.getId();
        // 注销该用户的 Session 会话 (从持久库删除此Session)
        SaSession session = StpUtil.getSessionByLoginId(id);
        if (session != null) {
            session.logout();
        }
        // 强制指定账号注销下线
        StpUtil.logout(id);
        return SaResult.ok();
    }

    @PostMapping("/kickout")
    public SaResult kickout(@RequestBody User userDTO) {
        Long id = userDTO.getId();
        // 注销该用户的 Session 会话 (从持久库删除此Session)
        SaSession session = StpUtil.getSessionByLoginId(id);
        if (session != null) {
            session.logout();
        }
        // 将指定账号指定端踢下线
        StpUtil.kickout(id);
        return SaResult.ok();
    }

}